/*
 * @Author: hejian@myhexin.com 
 * @Date: 2018-12-22 14:31:08 
 * @Last Modified by: hejian@myhexin.com
 * @Last Modified time: 2019-01-15 19:04:55
 */

var Meter = (function () {
	var options = {
		// 一些样式的设置
		styles: {
			// 起始角度
			sAngle: 0.88,
			// 结束角度
			eAngle: 2.12,
			// 外环的设置参数
			area: {
				// 道道线渐变色
				colors: {
					'0': '#26a10f',
					'0.15': '#3ca618',
					'0.27': '#f6bf60',
					'0.75': '#fe6c49',
					'0.93': '#ed3f36',
					'1': '#e93030'
				},
				// 道道线密集程度
				scaleLength: 10,
				// 道道线颜色
				lineColor: '#fff'
			}
		}
	};
	var element,
		context,
		styles,
		sAngle,
		eAngle,
		areaStyle;
		// 对象拷贝
		var extend = function (obj1, obj2) {
			for (var k in obj2) {
				if (obj1.hasOwnProperty(k) && typeof obj1[k] == 'object') {
					extend(obj1[k], obj2[k]);
				} else {
					obj1[k] = obj2[k];
				}
			}
		}
	// 计算内外圆半径
	var calcLocation = function (r, end) {
		return {
			x: options.centerPoint.x + r * Math.cos(Math.PI * end),
			y: options.centerPoint.y + r * Math.sin(Math.PI * end)
		};
	}
	// 计算转动的角度
	var calcValueRange = function (value) {
		var data = options.data.area,
			index = data.length - 1;
		for (var i = index; i >= 0; i--) {
			if (value >= data[i].min && value < data[i].max) {
				index = i;
			}
		};
		var r = (eAngle - sAngle) / data.length,
			s = r * index + sAngle,
			e = r * (index + 1) + sAngle,
			o = data[index];
		return {
			range: (value - o.min) / (o.max - o.min) * (e - s) + s,
			index: index
		};
	}
	// 跟读设置的属性，进行画圆
	var drawCircle = function (opts, flag) {
		var x = opts.x || options.centerPoint.x,
			y = opts.y || options.centerPoint.y,
			s = opts.start || 0,
			e = opts.end || 2;
		context.beginPath();
		context.moveTo(x, y);
		context.arc(x, y, opts.r, Math.PI * s, Math.PI * e);
		context.closePath();
		context.fillStyle = opts.style;
		context.fill();

	}
	// 设置外环区域
	var drawArea = function (valueRange) {
		// 创建渐变颜色
		var grad = context.createLinearGradient(0, 0, options.radius * 2, 0);
		for (var k in areaStyle.colors) {
			grad.addColorStop(k, areaStyle.colors[k]);
		}
		// 外环的灰色背景
		drawCircle({
			r: options.radius,
			start: sAngle,
			end: eAngle,
			style: "#dadada"
		});
		// 外环的高亮背景
		drawCircle({
			r: options.radius,
			start: sAngle,
			end: valueRange.range,
			style: grad
		});
		// 外环的白色填充背景
		drawCircle({
			r: options.radius - options.setting.areaRadius,
			style: '#fff',
			start: sAngle,
			end: eAngle
		});
	}
	// 设置内环区域
	var drawValueRange = function (valueRange) {
		// 创建渐变色
		var grad = context.createLinearGradient(0, 0, options.radius * 2, 0);
		for (var k in areaStyle.colors) {
			grad.addColorStop(k, areaStyle.colors[k]);
		}
		// 内环的灰色背景
		drawCircle({
			r: options.radius - options.setting.innerRadius - options.setting.innerMarin,
			start: sAngle,
			end: eAngle,
			style: '#ccc'
		});
		// 内环的高亮背景
		drawCircle({
			r: options.radius - options.setting.innerRadius - options.setting.innerMarin,
			start: sAngle,
			end: valueRange.range,
			style: grad
		});
		// 内环的填充背景
		drawCircle({
			r: options.radius - options.setting.innerRadius - options.setting.rangeWidth - options.setting.innerMarin,
			style: '#fff'
		});
	}
	// 填充文字
	var fillText = function (opts) {
		context.font = opts.font;
		context.fillStyle = opts.color;
		context.textAlign = opts.align || 'center';
		context.textBaseline = opts.vertical || 'middle';
		context.moveTo(opts.x, opts.y);
		context.fillText(opts.text, opts.x, opts.y);
	}
	// 内部文字
	var drawInnerContent = function (text) {
		// 配置的title
		var data = options.data;
		// 设置标题
		fillText({
			font: options.setting.titleSize,
			color: '#666',
			text: data.title,
			x: options.radius,
			y: options.radius + options.setting.titleMargin
		});
		// 设置等级
		fillText({
			font: options.setting.lableSize,
			color: '#e93030',
			text: text,
			x: options.radius,
			y: options.radius + options.setting.lableMargin
		});
	}

	var drawLine = function (line) {
		context.beginPath();
		context.moveTo(line.start.x, line.start.y);
		context.lineTo(line.end.x, line.end.y);
		context.closePath();
		context.strokeStyle = line.style;
		context.lineWidth = line.width || 1;
		context.stroke();
	}

	var drawTickMarks = function () {
		var scaleLength = areaStyle.scaleLength,
			data = options.data.area,
			len = scaleLength * 4,
			range = (eAngle - sAngle) / len;

		for (var j = 1; j < len; j++) {
			drawLine({
				start: calcLocation(options.radius, sAngle + range * j),
				end: calcLocation(options.radius - options.setting.innerRadius, sAngle + range * j),
				style: areaStyle.lineColor,
				width: j % scaleLength == 0 ? options.setting.scaleWidth : options.setting.scaleWidth
			});
		}
	}

	var drawing = function (w, h) {
		var value = options.data.value,
			valueTemp = options.data.area[0].min;

		var timer = setInterval(function () {
			context.clearRect(0, 0, w, h);
			context.fillStyle = "#fff";
			context.fillRect(0, 0, w, h);

			valueTemp = valueTemp + 10 > value ? value : valueTemp + 10;
			var valueRange = calcValueRange(valueTemp);
			// 最终结果的索引
			var index = valueRange.index;
			var area = options.data.area;
			// 外面的环
			drawArea(valueRange);
			// 里面的线
			drawValueRange(valueRange);
			// 白色到道道线
			drawTickMarks();
			if (valueTemp === value) {
				// 内部文字描述
				drawInnerContent(area[index].text);
				clearInterval(timer);
			}
		}, 10);
	}

	var exports = {};

	exports.setOptions = function (opts) {
		extend(options, opts);
		styles = options.styles;
		sAngle = styles.sAngle;
		eAngle = styles.eAngle;
		areaStyle = styles.area;

		element = typeof options.element == 'string' ? document.getElementById(options.element) : options.element;
		context = element.getContext('2d');
		return exports;
	};

	exports.init = function () {
		drawing(element.offsetWidth, element.offsetHeight);
		return exports;
	}
	return exports;
})();